/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package net.ubinow.mflex.widgets;

import java.util.Hashtable;

import javax.microedition.lcdui.Image;

import net.ubinow.mflex.baseui.ICommandBar;
import net.ubinow.mflex.baseui.IStatefulView;
import net.ubinow.mflex.baseui.WFont;
import net.ubinow.mflex.data.IDataItem;
import net.ubinow.mflex.events.AbsEventPublisher;
import net.ubinow.mflex.events.Event;
import net.ubinow.mflex.events.IEventSubscriber;
import net.ubinow.mflex.util.Constants;

/**
 *
 * @author Josh
 */
public abstract class AbsView extends AbsEventPublisher implements IStatefulView, IEventSubscriber {
    
    protected String _id = Constants.UNDEFINED;
    protected int _x = 0;
    protected int _y = 0;
    protected int _width = 0;
    protected int _height = 0;
    
    protected int _viewableWidth = 0;  // the actual viewable space for the widgets aka body of the view
    protected int _viewableHeight = 0; // the actual viewable space for the widgets aka body of the view
    
    protected int _paddingW = 0;
    protected int _paddingH = 0;
    
    protected WFont _bodyFont = null;
    protected WFont _headerFont = null;
    protected WFont _commandFont = null;
    
    protected int _bgColour = -1;
    protected Image _bgImage = null;     
    
    protected ICommandBar _cmdBar = null;        
    
    public AbsView( int x, int y, int width, int height, WFont defaultFont ){
        
        _x = x;
        _y = y;
        _width = _viewableWidth = width;
        _height = _viewableHeight = height;      
        
        setDefaultFont( defaultFont );                
    }
    
    //<editor-fold defaultstate="collapsed" desc="getters/setters implementatoin of IWidget">
    public String getID() {
        return _id;
    }

    public void setID(String id) {
        _id = id;
    }

    public int getX() {
        return _x; 
    }

    public void setX(int x) {
        _x = x;
    }

    public int getY() {
        return _y; 
    }

    public void setY(int y) {
        _y = y;
    }
    
    private int _orgX = -1;
    private int _orgY = -1;
    
    public void setOrgPos( int x, int y ){
        _orgX = x; 
        _orgY = y; 
        resetPos();
    }
    
    public void resetPos(){
        _x = _orgX;
        _y = _orgY;
    } 
    
    public int getOrgX(){
        return _orgX;
    }
    public int getOrgY(){
        return _orgY;
    }
    
    public int getBottomY() {
        return _y+_height;
    }
    
    public int getBottomY( boolean includeHeight ) {
        return getBottomY();
    }
    
    public void setPos( int x, int y ){
        _x = x;
        _y = y; 
    }

    public int getWidth() {
        return _width; 
    }

    public void setWidth(int w) {
        _width = w;
    }

    public int getHeight() {
        return _height;
    }
    
    public int getViewableHeight(){
        return _viewableHeight;
    }    

    public void setHeight(int h) {
        _height = h; 
    }

    public int getPaddingW() {
        return _paddingW;
    }

    public void setPaddingW(int padding) {
        _paddingW = padding; 
    }

    public int getPaddingH() {
        return _paddingH;
    }

    public void setPaddingH(int padding) {
        _paddingH = padding; 
    }   
    
    public int getTotalWidth(){
        return getPaddingW()+getWidth();
    }
    
    public int getTotalHeight(){
        return getPaddingH()+getHeight();
    }

    /** body font **/ 
    public void setFont( WFont font) {
        _bodyFont = font; 
    }

    /** body font **/ 
    public WFont getFont() {
        return _bodyFont; 
    }
    
    /** set the font you would like used to render the text on the header **/ 
    public void setHeaderFont( WFont font ){
        _headerFont = font; 
    }
    
    /** set the font you would like used to render the text on the commadn bar **/ 
    public void setCommandFont( WFont font ){
        _commandFont = font; 
    }
    
    /** sets the HeaderFont, BodyFont, and CommandFont to the font passed in as the parameter **/ 
    public void setDefaultFont( WFont font ){
        _headerFont = font;
        _bodyFont = font;
        _commandFont = font;       
    }
    
    public void setBG( Image bg ){
        _bgImage = bg; 
    }
    
    public void setBG( int colour ){
        _bgColour = colour;
    }

    public void setIsVisible( boolean visible ){
        // TODO: implement this
    }
    
    public boolean isVisible() {
        // TODO: implement this 
        return true;
    }
    
    public int maxLayers(){
        return 1; 
    }
    
    public boolean isSelectable(){
        return false; 
    }
    
    public void setFocus( boolean focus ,int direction ){
        // do nothing
    }
    
    public boolean isAnimated(){
        return true; 
    }
    
    public boolean supportsTransitioning(){
        return false; 
    }
    //</editor-fold>       
    
    //<editor-fold defaultstate="collapsed" desc="command bar fields and methods">
    
    // TODO: implement the commadn bar 
    
    /**
     * @param cmdBar: object of type ICommandBar
     * @param dock: where to dock 
     **/
    public void setCommandBar( ICommandBar cmdBar, int dock ){
        _cmdBar = cmdBar; 
        
        int x = (Constants.MISC_SCREEN_WIDTH-_cmdBar.getWidth())>>1;
        
        if( (dock & Constants.ALIGN_BOTTOM) != 0 ){
            System.out.println("command bar height " + _cmdBar.getHeight() );
            _cmdBar.setPos( x, Constants.MISC_SCREEN_HEIGHT-_cmdBar.getHeight() ); 
            
            _viewableHeight -= _cmdBar.getHeight();
        }
        else if( (dock & Constants.ALIGN_TOP) != 0 ){
            // TODO:
        }
    }
    
    public ICommandBar getCommandBar(){
        return _cmdBar;
    }
    
    //</editor-fold>   
    
    //<editor-fold defaultstate="collapsed" desc="IEventSubscriber implementation">
    
    // stateful properties  - these include things such as what state is associated with this view 
    //                      - the previous view 
    //                      - commands? 
    //                      - attachments (such as data items associated with it, ie then the next view can can access the previous view for 
    //                        information/data (_previousView.getAttachment( "myAttachment" );
    protected IStatefulView _previousView = null; 
    protected Hashtable _attachments = null;
    protected Hashtable _attachmentsForArrays = null;
    
    protected boolean _isActiveSubscriber = true; 
    
    public boolean isActiveSubscriber(){
        return _isActiveSubscriber; 
    }
    
    public void setActiveSubscriber( boolean active ){
        _isActiveSubscriber = active;
    }
    
    public void handleEvent(Event evt) {
        // TODO: handle any general purpose events here then dispatch this 
        // event to it's Subscribers (as this is a general purpose class that the developer should not 
        // handle Subscribers here) 
        notifySubscribers( evt );
    }

    public IStatefulView getPreviousView() {
        return _previousView;
    }

    public void setPreviousView(IStatefulView view) {
        if( view != null )
            System.out.println( "View.setPreviousView: " + view.getID() );  
        _previousView = view;
    }

    public void flush() {
        System.out.println("Not supported yet - AbsView.flush");
    }

    public void addAttachment(String key, IDataItem value) {
        if( _attachments == null )
            _attachments = new Hashtable( Constants.AD_ATTACHMENT_SIZE );
        
        _attachments.put( key, value );
    }

    public IDataItem getAttachment(String key, boolean removeFromView) {
        if( _attachments == null || !_attachments.containsKey( key ) )
            return null;
        IDataItem result = (IDataItem)_attachments.get( key );
        
        if( removeFromView )
            _attachments.remove( key );
        
        return result;         
    }

    public void addAttachments(String key, IDataItem[] values) {
        if( _attachmentsForArrays == null )
            _attachmentsForArrays = new Hashtable( Constants.AD_ATTACHMENT_SIZE );
        
        _attachmentsForArrays.put( key, values );
    }

    public IDataItem[] getAttachments(String key, boolean removeFromView) {
        if( _attachmentsForArrays == null || !_attachmentsForArrays.containsKey( key ) )
            return null;
        IDataItem[] result = (IDataItem[])_attachmentsForArrays.get( key );
        
        if( removeFromView )
            _attachmentsForArrays.remove( key );
        
        return result;   
    }    
    
    //</editor-fold>
    
}
